/***************************************************
                   fpc/file/pace_save.c
*****************************************************/
#include "fpp.h"
#include <fcntl.h>
#include <float.h>
#include <pwd.h>
/***************************************************
ignore_pace: clone's markers will not be included in calc'ing extent for pace
************************************************************/

extern int Zbatch_flag;
extern FILE *fpace;
extern int save_fpc_safe(), filCheck();
extern void  getdatehead();
extern void  Zget_framework();
extern int GetSize();
extern FILE *graphQueryOpen();
extern void setmarkerposctg();
extern void sortmarkers();

static void pace_save_ctg();

int Zg;
char Zmap[50];
float Zfmin, Zfmax;
int Zimin=INT_MAX, Zimax=INT_MIN;

struct tmpMarks {
    int  pos, nclones;
    float global;
    char name[MARKER_SZ+1];
} *gMarks;
int max_gMarks=0, num_gMarks=0; 

static  char Zpre[50];
static char str[500];
static int seqby, tile_cnt, sent_cnt;
static char DBtype='o'; /* 8apr99 - gull/oracle is the database now */

/***********************************************************/
/* excuted in ace4_save
************************************************************/
void find_stretched_contigs(int i,int num)
{
int k, j, conv=100;

     j = ((contigs[num].right-contigs[num].left)+1)*conv;
     if (i <= j)  return;

     printf("\nCtg%d Framework %d BandLen %d (%d) Clones %d  FW %d\n", num, i,
           (contigs[num].right-contigs[num].left)+1, j,
            contigs[num].count, num_gMarks);
     for (k=0; k< num_gMarks; k++) 
         printf("%14s %8.1f %4d %3d\n", gMarks[k].name, gMarks[k].global, 
                   gMarks[k].pos, gMarks[k].nclones);
}

/***********************************************************************/
/* fred 5/28/03 -- changed global_pos to anchor_pos... not necessarily
 * always right.  If this really gets used, this needs to be fixed*/
void map_extent(int index, int ctg)
{
int num;
CLONE *clp;
struct marker *markerptr;
struct markerclone *clones;
struct markerctgpos *pos;

   markerptr =  arrp(markerdata, index, MARKER);
   if(markerptr == NULL) return;
   if (markerptr->anchor_bin[0] == '\0') return;

   if (markerptr->anchor_pos < Zfmin) Zfmin = markerptr->anchor_pos;
   if (markerptr->anchor_pos > Zfmax) Zfmax = markerptr->anchor_pos;

   if (num_gMarks >= max_gMarks) {
       max_gMarks+=20;
       gMarks = (struct tmpMarks *) realloc(gMarks, sizeof(struct tmpMarks)*max_gMarks);
       if (gMarks==NULL) {
           printf("***contig frameworks realloc\n");
           return;
       }
   } 
   strcpy(gMarks[num_gMarks].name, markerptr->marker);
   gMarks[num_gMarks].global = markerptr->anchor_pos;
   for (pos = markerptr->pos; pos != NULL; pos = pos->next)
           if (pos->ctg == ctg) {
              gMarks[num_gMarks].pos = pos->pos;
              break;
           }
   num=0;
   clp = arrp(acedata, markerptr->cloneindex, CLONE);
   if (clp->ctg == ctg) num++;
   for (clones = markerptr->nextclone; clones != NULL; clones = clones->nextclone) {
        clp = arrp(acedata, clones->cloneindex, CLONE);
        if (clp->ctg == ctg) num++;
   }
   gMarks[num_gMarks].nclones = num;
   num_gMarks++;
}
/*******************************************************************/
void make_Zmap(int num)
{
  struct passwd *uinfo;
  if (Proj.mapname[0]!='\0') {
      strcpy(Zpre, Proj.mapname);
      Zg = 1; 
  } else {
      uinfo = (struct passwd *) getpwuid((uid_t) geteuid());
      if (uinfo == NULL) {
         printf("**** Cannot get user id\n");
         //return -1;
	    uinfo = (struct passwd*)malloc(sizeof(struct passwd));
	    uinfo->pw_name = strdup("unknown");
      }
      strcpy(Zpre, uinfo->pw_name);
      Zg = 0;
  }
  sprintf(Zmap, "%sctg%d", Zpre, num);
  Zfmin = FLT_MAX; Zfmax = FLT_MIN;
  Zimin = INT_MAX; Zimax = INT_MIN;
  num_gMarks=0;
  if (max_gMarks==0) {
     max_gMarks=100;
     gMarks = (struct tmpMarks *) malloc(sizeof(struct tmpMarks)*max_gMarks);
     if (gMarks==NULL) {
           printf("***contig frameworks\n");
           return;
     }
  }
}

/*******************************************************************/
int Zmap_ace(FILE *fpace)
{
char buf[100];
struct tmpMarks tmp;
int j,k;

     if (!Zg) return Zfmax-Zfmin;

     for (k=0; k< num_gMarks-1; k++) 
       for (j=k+1; j< num_gMarks; j++) 
         if (gMarks[k].global > gMarks[j].global) {
            tmp = gMarks[k];
            gMarks[k] = gMarks[j];
            gMarks[j] = tmp;
         }

     if (FLT_MIN==Zfmax && FLT_MAX==Zfmin) { 
         if (!Zbatch_flag) {
             sprintf(buf,"No framework markers for contig %s", Zmap);
             displaymess(buf);
           }
           Zfmin = Zfmax = 0.0;
     }
     if (Zfmax == Zfmin) {
           Zfmax += 5.0;
           Zfmin -= 5.0;
     }
       
     fprintf(fpace,"\nMap : %s\n", Zmap);
     fprintf(fpace,"Extent %d %d\n", Zimin, Zimax);
     fprintf(fpace,"Contig_size %d\n", 
                ((Zimax - Zimin + 1) * Proj.avgbandsize)/1000);
     fprintf(fpace,"Default_view status-view\n");
     fprintf(fpace,"Map %s  Left %7.1f\n", Proj.mapname, Zfmin);
     fprintf(fpace,"Map %s  Right %7.1f\n", Proj.mapname, Zfmax);
     
     return Zfmax-Zfmin;
}

/*******************************************************************/
static int pace_open(char *s)
{
char buf[1024];

  if(strlen(dirName)>0) sprintf(buf, "%s/Pace", dirName);
  else sprintf(buf, "Pace");
  if(!filCheck(buf,"d")){
    if(strlen(dirName)==0) sprintf(buf,"mkdir ./Pace");
    else sprintf(buf,"mkdir %s%s",dirName,"/Pace");
    printf("adding Pace Directory\n");
    system(buf);
  }
  if(strlen(dirName)>0) 
    sprintf(buf, "%s/Pace/%s-%s.ace", dirName, fileName,s);
  else
    sprintf(buf, "Pace/%s-%s.ace", fileName,s);
  if((fpace = fopen(buf,"w")) == NULL ){
      displaymess("Cannot open file:");
      displaymess(buf);
      return -1; 
  }
  sprintf(buf,"Save file for Gull %s",buf);
  displaymess(buf);
  fprintf(fpace,"// Dump from FPC in Gull %s format\n", s);
  getdatehead(buf);
  fprintf(fpace, "// %s\n", buf); 
return 1;
}

/*******************************************************************/
static void pace_seq()
{
int i;
int  cnt=0;
    
  seqby=tile_cnt=sent_cnt=0; 
   if (!Zbatch_flag && !pace_open("seq")) return;
                 /* delete existing ones */
   fflush(fpace);
   if (Proj.mapname[0]!='\n' && !Zbatch_flag)
       for (i=1; i<=max_contig; i++) 
         if (contigs[i].seq > 0) 
          fprintf(fpace, "\n-D Map : %sctg%d\n",Proj.mapname, i);
   
   for (i=1; i<=max_contig; i++) 
     if (contigs[i].seq > 0) {
         pace_save_ctg(i);
         cnt++;
     }
  
  free(gMarks);
  max_gMarks=num_gMarks=0;
  if (DBtype=='o') {
     fprintf(fpace, "\nFramework: %s\n", Proj.mapname);
     Zget_framework();
     for (i=0; i< FWcnt; i++) 
         if (arrp(markerdata, FWmarks[i].index, MARKER)->frame_type==FRAME)
             fprintf(fpace, "FW %16s %8.1f F\n", FWmarks[i].name, FWmarks[i].pos); 
         else
             fprintf(fpace, "FW %16s %8.1f P\n", FWmarks[i].name, FWmarks[i].pos); 
     free(FWmarks);
  }
  fclose(fpace);
  if (tile_cnt || sent_cnt) 
     sprintf(str,"Sequenced Contigs %d Tile %d Sent %d  External %d", cnt, tile_cnt, sent_cnt, seqby);
  else  
     sprintf(str,"No clones with sequence status; output file is empty");
  
  displaymess(str);
}

/*******************************************************************
                 DEF: pace_ctg
for a contig, output each clones:
  has a sequence status that is not equal to 0, Cancelled or Avoid
**********************************************************************/
static void pace_ctg(int num)
{
  tile_cnt=sent_cnt=0; 
   sprintf(str,"ctg%d",num);
   if (!pace_open(str)) return;
   pace_save_ctg(num);
   fclose(fpace);

   if (tile_cnt || sent_cnt) {
     sprintf(str,"Tile %d Total %d  ", tile_cnt, sent_cnt);
     displaymess(str);
   }
   else  
    displaymess("No clones with sequence status; file is empty");
}

/*******************************************************************/
static void pace_save_ctg(int num)
{  
  CLONE *clone;
  struct markertop *topmarkerptr;
  struct marker *markerptr;
  struct remark *pointer;
  int i, c, found, x;
  int size, cnt1=0, cnt2=0;
  char msg[100], where[50];

  make_Zmap(num);
  for (c=contigs[num].start; c!= -1; c = clone->next)
  {
     clone = arrp(acedata, c, CLONE);
                 /* find framework markers to compute where map goes in pace */
     for (found=0, pointer=clone->remark; !found && pointer!=NULL; pointer=pointer->next) 
	if (strstr(pointer->message, "pace_ignore") != NULL) found=1;
     
     if(!found && Zg && clone->marker !=NULL){
         topmarkerptr = clone->marker;
         while(topmarkerptr != NULL){ /*for each marker */
           map_extent(topmarkerptr->markerindex, num);
	   topmarkerptr = topmarkerptr->nextmarker;
         }
      }
     /* if(!IsSeq(clone))  continue; CHG: CES requested CANCELLED be dumped also **/
     if (clone->seqstat==0)  continue; 

     msg[0]='\0';
     for (found=0, pointer=clone->remark; !found && pointer!=NULL; 
           pointer=pointer->next)
     {
	     if (strstr(pointer->message, "GSC") != NULL) {
                 found=1; 
                 sprintf(msg,"Sequenced_by GSC");
             }
	     else if (strstr(pointer->message, "Sequenced_by") != NULL) {
                 x = sscanf(pointer->message, "Sequenced_by %s", where);
                 if (x==1) {
                     found=1;
                     sprintf(msg,"Sequenced_by %s",where);
                 }
                 else 
                     printf("Warning: clone %s, ignore remark: %s\n",clone->clone, 
                         pointer->message);
             }
     }
     if (found==0) sprintf(msg,"Sequenced_by SC");
     else seqby++;

     fprintf(fpace,"\nSequence : \"%s\"\n",clone->clone);

     if(clone->seqstat == TILE){
         cnt1++;
         clone->seqstat = SENT;
         update = TRUE;
     }
     else cnt2++;
       
     fprintf(fpace,"Map %s Left %d\n", Zmap, clone->x);
     fprintf(fpace,"Map %s Right %d\n", Zmap, clone->y);
     fprintf(fpace,"Shotgun_type %s\n", seqtype[clone->seqtype]); /* ADD 19mar99 */
     fprintf(fpace,"%s\n", msg);
     if (Proj.mapname[0] != '\0')
          fprintf(fpace,"Chromosome %s\n", Proj.mapname);
        
     if (Zimin > clone->x) Zimin = clone->x;
     if (Zimax < clone->y) Zimax = clone->y;
     
     if (DBtype=='o') {
         if ((size = GetSize(clone))!=0)
            fprintf(fpace,"Sequence_length %d\n", size/1000);
         else
            fprintf(fpace,"Sequence_length %d\n", 
              ((clone->y - clone->x +1) * Proj.avgbandsize)/1000);

         topmarkerptr = clone->marker;
         while(topmarkerptr != NULL){ /*for each marker */
	   markerptr = arrp(markerdata,topmarkerptr->markerindex,MARKER);
	   if(markerptr != NULL) {
              if (markerptr->type==markSTS) fprintf(fpace, "Marker  %s\n",markerptr->marker);
           }
	   topmarkerptr = topmarkerptr->nextmarker;
         }
         for (pointer=clone->remark; pointer!=NULL; pointer=pointer->next) {
	    fprintf(fpace, "Remark %s\n", pointer->message);
         }
         for (pointer=clone->fp_remark; pointer!=NULL; pointer=pointer->next) {
	    fprintf(fpace, "Fpc_remark %s\n", pointer->message);
         }
     }
  }
  if (cnt1 || cnt2) {
     tile_cnt += cnt1;
     sent_cnt += cnt2;
     i = Zmap_ace(fpace);
  }
}

/*******************************************************************/
static int check2ctg(char *temp)
{
  int result;

  if(sscanf(temp,"%d",&result)){
    if(result<= max_contig){
      if(contigs[result].count!=0)
	return result;
      else
	displaymess("There are no clones in this contig");
    }
    else
      displaymess("Must be lower than the max contig");
  }
  else
    displaymess("Please input an integer");
  return 0;
}

static void request2ctg(char *temp)
{	       
  int ctg=0;

  ctg = check2ctg(temp);
  if(ctg) pace_ctg(ctg);
}

static void sub_ctg()
{
  int ctg=0;

  ctg = check2ctg(req2ctg);
  if(ctg) pace_ctg(ctg);
}

void pacectgpick()
{
  if(graphActivate(gsubmit)){ 
    graphClear();
    graphPop();
  }
  else{ 
    gsubmit = graphCreate (TEXT_FIT,"Save as Pace",.2,.2,.3,.16) ;
  }
  
  graphButton("Save Sequenced Contigs",pace_seq,2.0,2.0);
  
  graphText("Contig:",2.0,5.0);
  graphTextEntry(req2ctg, 5, 9.0, 5.0,request2ctg);
  graphButton("Save",sub_ctg,15.0,5.0);

  graphButton("Close",graphDestroy,5.0,7.0);
  graphRedraw();
}
/*******************************************************/
void Zpace_batch(FILE *fp, int s) 
{
char buf[1024];
  fpace = fp;
  if (s==2) fprintf(fpace,"// Batch Dump from FPC for SC Oracle tracking database\n");
  else fprintf(fpace,"// Batch Dump from FPC for SC Pace database\n");
  getdatehead(buf);
  fprintf(fpace, "// %s\n", buf); 
  if (s==2) DBtype = 'o';
  else DBtype = 'p';
  pace_seq(); 
            /* changes Tile to Sent, to need to save to indicate sent */
  if (tile_cnt) {
      save_fpc_safe();
      printf("Save fpc file\n");
  }
}

/********************************************************************
                    save order marker list
 fred 4/14/03
*********************************************************************/
void save_ordered_marker_list(){
  char fileName[MAXPATHLEN+1];
  FILE *fp;
  int ctg, save_ctg;
  struct markerlist *mptr;
  MARKER *mkp;

  fileName[0]='\0';
  if(!(fp = graphQueryOpen(dirName, fileName, "txt","w","Choose file name")))
    return;
  save_ctg = currentctg;

  for(ctg=1; ctg<=max_contig; ctg++){
    if(contigs[ctg].count==0) continue;
    currentctg = ctg;
    fprintf(fp, "Ctg%d\n", currentctg);
    setmarkerposctg(); /* get markers*/
    sortmarkers();
    for(mptr=markerlistroot; mptr!=NULL; mptr=mptr->next){
      mkp = arrp(markerdata,mptr->markerindex,MARKER);
      fprintf(fp, "%-17s %d\n", mkp->marker, mptr->midpt);
    }
  }
  fclose(fp);

  currentctg=save_ctg;
  setmarkerposctg();
  sortmarkers();
}

/********************************************************************
                    save markers as excel
*********************************************************************/
void save_markers_as_excel() 
{
  int i, cnt;
  struct markerclone *p;
  struct marker *marker;
  CLONE *clone;
  FILE *FP;

/* find all clones for marker */
  FP = fopen("markers.excel","w");
  for(cnt=i=0;i<arrayMax(markerdata);i++)
  {
      marker = arrp(markerdata,i,MARKER);
      clone = arrp(acedata,marker->cloneindex,CLONE);
      fprintf(FP,"%s\t%s",marker->marker,clone->clone);
      cnt++;
      p = marker->nextclone;
      for (p = marker->nextclone;p!=NULL; p = p->nextclone) {
        clone = arrp(acedata,p->cloneindex,CLONE);
        fprintf(FP,"\t%s",clone->clone);
        cnt++;
      }
      fprintf(FP,"\n");
   }
   fclose(FP);
   fprintf(stdout,"Wrote %d markers (%d clone hits) to markers.excel\n",
                  arrayMax(markerdata),cnt);
}
/*****************************************************
               DEF: save_clone_sizes
cari 1mar04 add
******************************************************/
void save_clone_sizes()
{
int i, cnt1=0, size;
CLONE *clp;
FILE *FP;

  FP = fopen("clone.sizes","w");
  for (i=0; i<arrayMax(acedata); i++) {
      clp = arrp(acedata, i, CLONE);
      if (clp->clone[0]=='!') continue;
      if ((size=GetSize(clp))!=0) {
          fprintf(FP,"%s %d\n",clp->clone,size);
          cnt1++;
      }
  }
  printf("Wrote %d sizes into file clone.sizes\n",cnt1);
  fclose(FP);
}
